﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace PercolationTree.Drawing
{
    class DrawableFunction : IDrawable
    {
        private IList<Point> m_Points;
        public DrawableFunction(IList<Point> points)
        {
            m_Points = points;
        }
        public void draw(PaintEventArgs e)
        {
            Brush blackSolidBrush = new SolidBrush(Color.Black);
            Pen coordinatePen = new Pen(blackSolidBrush, 2);
            Pen coordinateLinesPen = new Pen(Color.LightGray, 1);
            Pen functionPen = new Pen(Color.Blue, 1);
            Font textFont = new Font(FontFamily.GenericMonospace, 12);
            int width = e.ClipRectangle.Width;
            int height = e.ClipRectangle.Height;

            // Draw Coordinates
            int xMax = m_Points.Select(p => p.X).Max();
            int yMax = m_Points.Select(p => p.Y).Max();
            for (int i = 0; i < width; i += width / 10)
            {
                e.Graphics.DrawLine(coordinatePen, i, height - 5, i, height + 5);
                e.Graphics.DrawLine(coordinateLinesPen, i, 0, i, height);
                e.Graphics.DrawString((xMax * i / width).ToString(), textFont, blackSolidBrush, new Point(i, height - 20));
            }
            for (int i = 0; i < height; i += height / 10)
            {
                e.Graphics.DrawLine(coordinatePen, -5, height - i, 5, height - i);
                e.Graphics.DrawLine(coordinateLinesPen, 0, height - i, width, height - i);
                e.Graphics.DrawString((yMax * i / height).ToString(), textFont, blackSolidBrush, new Point(0, height - i));
            }
            e.Graphics.DrawLine(coordinatePen, 0, height, width, height);
            e.Graphics.DrawLine(coordinatePen, 0, 0, 0, height);

            // Draw Function
            e.Graphics.ScaleTransform(1, -1);
            e.Graphics.TranslateTransform(0, -e.ClipRectangle.Height);

            IList<Point> points = NormalizedPoints(e.ClipRectangle, m_Points);
            if (points.Count % 2 != 0)
                points.RemoveAt(points.Count - 1);
            GraphicsPath funcPath = new GraphicsPath();
            //funcPath.AddBeziers(points.ToArray());
            funcPath.AddLines(points.ToArray());
            e.Graphics.DrawPath(functionPen, funcPath);
        }
        private IList<Point> NormalizedPoints(Rectangle rect, IList<Point> points)
        {
            int xMax = points.Select(p => p.X).Max();
            int yMax = points.Select(p => p.Y).Max();
            IList<Point> normPoints = new List<Point>();
            foreach (Point p in points)
            {
                Point np = new Point(p.X * rect.Width / xMax, p.Y * rect.Height / yMax);
                normPoints.Add(np);
            }
            return normPoints;
        }
    }
}
